home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctjag86.arc / ATDISK.C < prev    next >
Text File  |  1986-05-23  |  11KB  |  365 lines

  1. /*
  2.  * ATDISK -- PC Tech Journal AT Hard Disk Performance Test
  3.  *
  4.  * Version 1.00
  5.  * Last modified 05/23/86
  6.  * Copyright (c) 1986, PC Tech Journal
  7.  * Program by: Paul Pierce, Ted Forgeron, Steven Armbrust
  8.  *
  9.  * Uses BIOS INT 13H to measure low-level performance.
  10.  * Uses DOS  INT 21H to measure high-level performance.
  11.  */
  12.  
  13. #include "dos.h"
  14.  
  15. /* System clock tick rate in ticks/second */
  16. #define TICK_RATE 18.20648
  17.  
  18. /* Number of trials for each test */
  19. #define TRIALS 1000
  20.  
  21. struct diskparam {
  22.         int     sectors;
  23.         int     heads;
  24.         int     cylinders;
  25.         int     drives;
  26. } diskparam[10];
  27.  
  28. char buffer[50 * 512];
  29.  
  30. /* Number of files for DOS file I/O test */
  31. #define FILES   10
  32. /* Size of each file for DOS file I/O test */
  33. #define FILESIZE 20000
  34. /* Size of each read/write request for DOS file I/O test */
  35. #define FILEBUF 2000
  36.  
  37. char filename[] = "C:ATDISK.~~0";
  38.  
  39. unsigned long tick();
  40. unsigned rand();
  41.  
  42. double drand()
  43. {
  44.  
  45.         return (double)rand() / 32767;
  46. }
  47.  
  48. #define READ_SECTORS    2
  49. #define GET_PARAM       8
  50. #define SEEK            12
  51.  
  52. main(argc, argv)
  53. int argc;
  54. char *argv[];
  55. {
  56.         register i, j, k;
  57.         unsigned long start;
  58.         unsigned long total;
  59.         unsigned trials;
  60.         int      f;
  61.  
  62.         trials = TRIALS;
  63.  
  64.         /*
  65.          * Get the disk drive parameters for each hard disk
  66.          * in the system.
  67.          */
  68.  
  69.         disk_io(GET_PARAM, 0x80, &diskparam[0], 0, 0, 0, 0);
  70.         for (i = 1; i < diskparam[0].drives; i++) {
  71.                 disk_io(GET_PARAM, 0x80 + i, &diskparam[i],
  72.                         0, 0, 0, 0);
  73.         }
  74.  
  75.         /*
  76.          * Display the disk characteristics.
  77.          */
  78.  
  79.         printf("\nATDISK -- PC Tech Journal AT Hard Disk ");
  80.         printf("Performance Test");
  81.         printf("\nVersion 1.00, Copyright (c) 1986 PC Tech ");
  82.         printf("Journal");
  83.         printf("\n\nHARD DISK CHARACTERISTICS\n");
  84.         printf("Drive      Sectors  Heads  Cylinders  Total ");
  85.         printf("space\n");
  86.         for (i = 0; i < diskparam[0].drives; i++) {
  87.                 total = diskparam[i].sectors * diskparam[i].heads;
  88.                 total *= diskparam[i].cylinders;
  89.                 total *= 512;
  90.                 printf("%3d       %5d   %5d     %5d     %10lu\n",
  91.                                 i,
  92.                                 diskparam[i].sectors,
  93.                                 diskparam[i].heads,
  94.                                 diskparam[i].cylinders,
  95.                                 total);
  96.         }
  97.  
  98.         printf("\nBIOS TEST OF DISK HARDWARE PERFORMANCE\n");
  99.  
  100.         /*
  101.          * Seek back and forth between tracks 0 and 1.
  102.          */
  103.  
  104.         for (i = 0; i < diskparam[0].drives; i++) {
  105.                 disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0, 0);
  106.                 start = tick();
  107.                 for (j = 0; j < trials/2; j++) {
  108.                         disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0,
  109.                                 1);
  110.                         disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0,
  111.                                 0);
  112.                 }
  113.                 total = tick() - start;
  114.                 printf("Drive %d track-track seek time: %4.1f ms",
  115.                         i, (double)total / ((double)trials) *
  116.                            1000.0 / TICK_RATE);
  117.                 printf("\n");
  118.         }
  119.  
  120.         /*
  121.          * Seek to random tracks.
  122.          */
  123.  
  124.         for (i = 0; i < diskparam[0].drives; i++) {
  125.                 disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0, 0);
  126.                 start = tick();
  127.                 for (j = 0; j < trials; j++) {
  128.                         disk_io(SEEK, 0x80 + i, buffer, 1, 0, 0,
  129.                                 (short)(drand()*
  130.                                 (diskparam[i].cylinders - 1)));
  131.                 }
  132.                 total = tick() - start;
  133.                 printf("Drive %d average seek time: %4.1f ms\n",
  134.                         i, (double)total / ((double)trials) *
  135.                            1000.0 / TICK_RATE);
  136.         }
  137.  
  138.         /*
  139.          * Measure transfer rate by repeatedly reading sectors
  140.          */
  141.  
  142.         for (i = 0; i < diskparam[0].drives; i++) {
  143.                 disk_io(READ_SECTORS, 0x80 + i, buffer, 1, 0, 0,
  144.                         0);
  145.                 start = tick();
  146.                 for (j = 0; j < trials; j++) {
  147.                         disk_io(READ_SECTORS, 0x80 + i, buffer,
  148.                                 diskparam[i].sectors, 0, 0, 0);
  149.                 }
  150.                 total = tick() - start;
  151.                 printf("Drive %d effective transfer rate: ", i);
  152.                 printf("%6.1f Kbytes/second\n",
  153.                         (((double)diskparam[i].sectors)*512.0) *
  154.                         (double)trials / ((double)total) /
  155.                         1024 * TICK_RATE);
  156.         }
  157.  
  158.         /*
  159.          * This section indicates overall system disk performance
  160.          * by using DOS calls to manipulate files.  It is only
  161.          * executed if the -d command line switch is used since
  162.          * the test writes to disk.
  163.          */
  164.  
  165.         if (argc == 1) {
  166.                 printf("\nType \"atdisk -d\" to run the DOS ");
  167.                 printf("TEST OF DISK SYSTEM PERFORMANCE.\n");
  168.                 printf("This test creates, writes, reads and ");
  169.                 printf("deletes ten files named \n");
  170.                 printf("atdisk.~~0 through atdisk.~~9.\n");
  171.         }
  172.         if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'd'){
  173.                 printf("\nDOS TEST OF DISK SYSTEM PERFORMANCE\n");
  174.                 printf("This test creates, writes, reads and ");
  175.                 printf("deletes ten 20,000 byte files.\n");
  176.                 printf("Best results are achieved with blank, ");
  177.                 printf("freshly-formatted disks.\n");
  178.                 for (k = 0; k < diskparam[0].drives; k++) {
  179.                         filename[0] = 'C' + k;
  180.                         start = tick();
  181.  
  182.                         /*
  183.                          * First create each file, write to it,
  184.                          * and close it.
  185.                          */
  186.  
  187.                         for (i = 0; i < FILES; i++) {
  188.                                 filename[11] = '0' + i;
  189.                                 f = dos_create(filename, 0);
  190.                                 for (j = 0; j < FILESIZE/FILEBUF;
  191.                                      j++) {
  192.                                         dos_write(f, buffer,
  193.                                                   FILEBUF);
  194.                                 }
  195.                                 dos_close(f);
  196.                         }
  197.  
  198.                         /*
  199.                          * Now reopen each file, read it, and
  200.                          * then delete it.
  201.                          */
  202.  
  203.                         for (i = 0; i < FILES; i++) {
  204.                                 filename[11] = '0' + i;
  205.                                 f = dos_open(filename, 0);
  206.                                 for (j = 0; j < FILESIZE/FILEBUF;
  207.                                      j++) {
  208.                                         dos_read(f, buffer,
  209.                                                  FILEBUF);
  210.                                 }
  211.                                 dos_close(f);
  212.                                 dos_delete(filename);
  213.                         }
  214.  
  215.                         total = tick() - start;
  216.                         printf("Drive %c:",'C' + k);
  217.                         printf("%6.1f seconds\n",
  218.                                 ((double)total) / TICK_RATE);
  219.                 }
  220.         }
  221. }
  222.  
  223. /*
  224.  * DOS file calls
  225.  *
  226.  * Each of these routines sets up the regs structure as
  227.  * specified in the DOS technical reference and then
  228.  * calls DOS using the intdos() function.
  229.  */
  230.  
  231.  
  232. /*
  233.  * DOS call 3C - create file
  234.  */
  235.  
  236. int
  237. dos_create(file, attribute)
  238.         char    *file;
  239.         int     attribute;
  240. {
  241.         struct REGS regs;
  242.  
  243.         regs.x.dx =(int)file;
  244.         regs.h.ah = 0x3C;
  245.         regs.x.cx = attribute;
  246.         intdos(®s, ®s);
  247.         if (regs.x.cflag) {
  248.                 printf("DOS error %d in create\n",
  249.                         regs.x.ax);
  250.                 exit(1);
  251.         }
  252.         return regs.x.ax;
  253. }
  254.  
  255. /*
  256.  * DOS call 3D - open file
  257.  */
  258.  
  259. int
  260. dos_open(file, mode)
  261.         char    *file;
  262.         int     mode;
  263. {
  264.         struct REGS regs;
  265.  
  266.         regs.x.dx = (int)file;
  267.         regs.h.ah = 0x3D;
  268.         regs.h.al = mode;
  269.         intdos(®s, ®s);
  270.         if (regs.x.cflag) {
  271.                 printf("DOS error %d in open\n",
  272.                         regs.x.ax);
  273.                 exit(1);
  274.         }
  275.         return regs.x.ax;
  276. }
  277.  
  278. /*
  279.  * DOS call 3E - close file
  280.  */
  281.  
  282. dos_close(handle)
  283.         int     handle;
  284. {
  285.         struct REGS regs;
  286.  
  287.         regs.x.bx = handle;
  288.         regs.h.ah = 0x3E;
  289.         intdos(®s, ®s);
  290.         if (regs.x.cflag) {
  291.                 printf("DOS error %d in close\n",
  292.                         regs.x.ax);
  293.                 exit(1);
  294.         }
  295. }
  296.  
  297. /*
  298.  * DOS call 3F - read file
  299.  */
  300.  
  301. int
  302. dos_read(handle, buffer, count)
  303.         int     handle;
  304.         char    *buffer;
  305.         int     count;
  306. {
  307.         struct REGS regs;
  308.  
  309.         regs.x.bx = handle;
  310.         regs.x.cx = count;
  311.         regs.x.dx = (int)buffer;
  312.         regs.h.ah = 0x3F;
  313.         intdos(®s, ®s);
  314.         if (regs.x.cflag) {
  315.                 printf("DOS error %d in read\n",
  316.                         regs.x.ax);
  317.                 exit(1);
  318.         }
  319.         return regs.x.ax;
  320. }
  321.  
  322. /*
  323.  * DOS call 40 - write file
  324.  */
  325.  
  326. int
  327. dos_write(handle, buffer, count)
  328.         int     handle;
  329.         char    *buffer;
  330.         int     count;
  331. {
  332.         struct REGS regs;
  333.  
  334.         regs.x.bx = handle;
  335.         regs.x.cx = count;
  336.         regs.x.dx = (int)buffer;
  337.         regs.h.ah = 0x40;
  338.         intdos(®s, ®s);
  339.         if (regs.x.cflag) {
  340.                 printf("DOS error %d in write\n",
  341.                         regs.x.ax);
  342.                 exit(1);
  343.         }
  344.         return regs.x.ax;
  345. }
  346.  
  347. /*
  348.  * DOS call 41 - delete file
  349.  */
  350.  
  351. dos_delete(file)
  352.         char    *file;
  353. {
  354.         struct REGS regs;
  355.  
  356.         regs.x.dx = (int)file;
  357.         regs.h.ah = 0x41;
  358.         intdos(®s, ®s);
  359.         if (regs.x.cflag) {
  360.                 printf("DOS error %d in delete\n",
  361.                         regs.x.ax);
  362.                 exit(1);
  363.         }
  364. }
  365.